package easycontroller.plugin.expand;


import easycontroller.plugin.Plugin;

import java.io.*;
import java.util.Properties;

public class FilePlugin extends Plugin {

    private File root;

    public String getName() {
        return "file";
    }

    {
        setName("file");
    }

    public String getDescription() {
        return "提供文件相关的操作,root配置参数配置根路径。\n" +
                "使用write(InputStream,String)将输入流持久化(不会关闭输入流,返回 0-成功,1-文件创建失败,2-文件已经存在禁止重复创建,3-文件写入时失败)\n" +
                "使用read(String,OutputStream)将文件读出(不会关闭输出流,返回 0-成功,1-文件不存在,2-文件读取时失败)\n" +
                "使用delete(String)将文件删除(返回 0-成功,1-文件本身就不存在,2-文件删除失败)\n" +
                "使用exists(String)做文件存在检测(返回true-存在,false-不存在)"
                + "\n使用rename(原文件,新文件)对文件进行重命名(返回 0-成功,1-原文件不存在,2-目标文件已存在,3-重命名失败,4-原文件不是文件)"
                ;
    }


    @Override
    public void start() {
        String rootPath = null;
        if (config != null) {
            rootPath = config.get("root");
        }
        if (rootPath == null) {
            Properties properties = System.getProperties();
            rootPath = properties.getProperty("user.home") + File.separator + ".file";
            System.out.println("文件插件根路径:" + rootPath);
        }
        root = new File(rootPath);
        if (!root.exists()) {
            if (!root.mkdir()) {
                throw new RuntimeException("文件根路径初始化失败");
            }
        }
    }

    @Override
    public void stop() {
    }

    @Override
    public void restart() {
        start();
    }

    public boolean exists(String path) {
        return new File(root, path).exists();
    }

    public int delete(String path) {

        path = toRelativePath(path);

        File file = new File(root, path);
        if (!file.exists()) {
            return 1;
        }
        if (!file.delete()) {
            return 2;
        }

        clearEmptyParent(path);

        return 0;
    }

    public void clearEmptyParent(String path) {
        int index = path.lastIndexOf("/");
        if (index != -1) {
            String dirPath = path.substring(0, index);
            File dir = new File(root, dirPath);
            File[] files = dir.listFiles();
            if (files == null || files.length == 0) {
                if (dir.delete()) {
                    clearEmptyParent(path);
                }
            }
        }
    }

    public int rename(String old, String now) {
        old = toRelativePath(old);
        File oldFile = new File(root, old);
        if (!oldFile.exists()) {
            return 1;
        }
        if (!oldFile.isFile()) {
            return 4;
        }

        now = toRelativePath(now);

        File nowFile = new File(root, now);
        if (nowFile.exists()) {
            return 2;
        }
        //确保路径存在
        int i = checkMkParent(now);
        if (i != 0) {
            return 3;
        }
        boolean b = oldFile.renameTo(nowFile);
        if (b) {
            clearEmptyParent(old);
            return 0;
        } else {
            clearEmptyParent(now);
            return 3;
        }
    }

    public int read(String path, OutputStream outputStream) {

        path = toRelativePath(path);

        File file = new File(root, path);

        if (!file.exists()) {
            //表示文件不存在无法读取
            return 1;
        }

        //对文件进行读取操作
        return read(file, outputStream);
    }


    private int read(File file, OutputStream outputStream) {

        try {
            FileInputStream inputStream = new FileInputStream(file);
            byte[] buff = new byte[1024];
            int len;
            try {
                while ((len = inputStream.read(buff)) != -1) {
                    outputStream.write(buff, 0, len);
                }
                outputStream.flush();
            } catch (Exception ignore) {
                return 2;
            }

            inputStream.close();

        } catch (FileNotFoundException e) {
            return 1;
        } catch (IOException e) {
            return 2;
        }
        //关流操作

        return 0;
    }



    //判断父路径是否存在,不存在就创建父路径
    private int checkMkParent(String path) {
        int index = path.lastIndexOf("/");
        if (index != -1) {
            String dirPath = path.substring(0, index);
            File dir = new File(root, dirPath);
            if (!dir.exists()) {
                if (!dir.mkdirs()) {
                    return 1;
                }
            }
        }
        return 0;
    }

    private String toRelativePath(String path) {

        //处理成相对的
        if (path.startsWith("/")) {
            path = path.substring(1);
        }
        return path;
    }

    public int write(InputStream inputStream, String path) {
        path = toRelativePath(path);
        int i = checkMkParent(path);
        if (i != 0) {
            return i;
        }
        File file = new File(root,path);

        if (file.exists()) {
            return 2;
        }

        try {
            if (!file.createNewFile()) {
                return 1;
            }
        } catch (Exception ignore) {
            return 1;
        }


        return write(inputStream, file);
    }


    //将文件转移
    private int write(InputStream inputStream, File file) {
        try {
            OutputStream outputStream = new FileOutputStream(file);
            byte[] buff = new byte[1024];
            int len = 0;
            try {
                while ((len = inputStream.read(buff)) != -1) {
                    outputStream.write(buff, 0, len);
                }
                outputStream.flush();
            } catch (Exception ignore) {
                return 3;
            }
            outputStream.close();
        } catch (IOException e) {
            return 3;
        }

        return 0;

    }

}
